home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / flip / light.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  471 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    Better lighting constants
  19.  * By Gavin Bell for Silicon Graphics, Inc.
  20.  * 12/2/88
  21. */
  22. #include <gl.h>
  23. #include <device.h>
  24. #include <stdio.h>
  25.  
  26. #include "light.h"
  27.  
  28. /*
  29.  *    When changing materials/models, keep track of the last one so we
  30.  * don't immediately lmbind it again
  31.  */
  32. static int curmaterial = -1;
  33. static int curmodel = -1;
  34.  
  35. /* Pre-define a few things declared at the bottom of this file */
  36. extern float ldef_material[][15];
  37. extern float ldef_light[][14];
  38. extern float ldef_lmodel[][10];
  39.  
  40. /* This keeps track of which lights are on/off */
  41. static int onoff[MAXLIGHTS];
  42.  
  43. static float ldef_alpha[] =
  44. {
  45.     ALPHA, 0.2, LMNULL
  46. };
  47.  
  48. #define SIZE(x) sizeof(x)/sizeof(float)
  49.  
  50. void
  51. defineshading(void)
  52. {
  53.     int i, alpha;
  54.     char machinetype[32];
  55.     
  56.     /*
  57.      * Only define transparent materials if machine is capable of
  58.      * blending
  59.      */
  60.     if (getgdesc(GD_BLEND))
  61.         alpha = 1;
  62.     else alpha = 0;
  63.  
  64.     /* define material properties */
  65.     for (i = 0; i < NUM_MATERIALS; i++)
  66.     {
  67.         lmdef (DEFMATERIAL, i+1, SIZE(ldef_material[i]), ldef_material[i]);
  68.         if (alpha)
  69.         {
  70.             lmdef(DEFMATERIAL, i+1+NUM_MATERIALS,
  71.                 SIZE(ldef_material[i]), ldef_material[i]);
  72.             lmdef(DEFMATERIAL, i+1+NUM_MATERIALS,
  73.                 SIZE(ldef_alpha), ldef_alpha);
  74.         }
  75.     }
  76.  
  77.     /* define lighting model */
  78.     for (i = 0 ; i < NUM_LMODELS; i++)
  79.         lmdef (DEFLMODEL, i+1, SIZE(ldef_lmodel[i]), ldef_lmodel[i]);
  80.  
  81.     /* define light source properties */
  82.     for (i = 0 ; (i < NUM_LIGHTS) && (i < MAXLIGHTS); i++)
  83.         lmdef (DEFLIGHT, i+1, SIZE(ldef_light[i]), ldef_light[i]);
  84.  
  85.     /* Turn all the lights off */
  86.     for (i = 0; i < MAXLIGHTS; i++) onoff[i] = 0;
  87. }
  88.  
  89. void
  90. setmaterial(int m)
  91. {
  92.     /* do not pick same material twice */
  93.     if (m == curmaterial) 
  94.         return;
  95.  
  96.     if (m < 0)
  97.         fprintf(stderr, "setmaterial error: material %d undefined\n", m);
  98.     else
  99.     {    /* Use the material */
  100.         curmaterial = m;
  101.         lmbind(MATERIAL, curmaterial+1);
  102.     }
  103. }
  104.  
  105. /*
  106.  *    Turn given light on or off:  Note that the light's position will
  107.  * be affected by what's currently on the viewing stack.  Note also
  108.  * that this routine assumes that LIGHT0,LIGHT1, etc. are #defined in
  109.  * numerical order!
  110.  */
  111. /*
  112.  *    Enhancement possibility:  store the light number in the onoff
  113.  * array, in the position it is bound (i.e. if light[4] is bound to
  114.  * LIGHT2, then onoff[2] == 4).  When turning on or off, look for the
  115.  * light in onoff; if found, turn off by setting onoff[n] = 0 and
  116.  * lmbinding it.  If not found, look for an empty space in onoff and
  117.  * bind it there.  If no empty space if found, print a warning.
  118.  */
  119. void
  120. switch_light(int m)
  121. {
  122.     if (m > NUM_LIGHTS || m < 0 || m > MAXLIGHTS)
  123.     {
  124.         fprintf(stderr, "switch_light error: light %d undefined\n", m);
  125.     }
  126.     else
  127.     {
  128.         if (onoff[m])    /* Light is currently on */
  129.             onoff[m] = 0;
  130.         else
  131.             onoff[m] = m+1;
  132.         lmbind(LIGHT0 + m, onoff[m]);
  133.     }
  134. }
  135.  
  136. /*
  137.  *    This routine re-binds lights.  Use it when you desire moving
  138.  * lights (re-define the viewing transformation matrix, call this
  139.  * routine to get transformed lights, then draw your objects).
  140.  */
  141. void
  142. rebind_lights(void)
  143. {
  144.     int i;
  145.     for (i = 0 ; (i < MAXLIGHTS) && (i < NUM_LIGHTS) ; i++)
  146.     {
  147.         lmbind(LIGHT0 + i, onoff[i]);
  148.     }
  149. }
  150.  
  151. void
  152. setmodel(int m)
  153. {
  154.     if (m == curmodel)
  155.         return;
  156.     if (m < 0)
  157.     {
  158.         fprintf(stderr, "setmodel error: model %d undefined\n", m);
  159.     }
  160.     else
  161.     {
  162.         curmodel = m;
  163.         lmbind(LMODEL, curmodel+1);
  164.     }
  165. }
  166.  
  167. void
  168. resetmodel()
  169. {
  170.     lmbind(LMODEL, curmodel+1);
  171. }
  172.  
  173. static float lmat[] =
  174. {
  175.     EMISSION, 0.0, 0.0, 0.0,
  176.     DIFFUSE, 0.0, 0.0, 0.0, 
  177.     AMBIENT, 0.0, 0.0, 0.0,
  178.     SHININESS, 0.0, 
  179.     LMNULL
  180. };
  181.  
  182. int
  183. draw_lights(void)
  184. {
  185.     void draw_icosa(void);
  186.     int i, numdrawn;
  187.  
  188.     numdrawn = 0;
  189.     for (i = 0 ; i < NUM_LIGHTS; i++)
  190.     {
  191.         if (!onoff[i]) continue;
  192.  
  193.         lmat[1] = ldef_light[i][1] * 0.4;
  194.         lmat[2] = ldef_light[i][2] * 0.4;
  195.         lmat[3] = ldef_light[i][3] * 0.4;
  196.  
  197.         lmat[5] = ldef_light[i][1] ;
  198.         lmat[6] = ldef_light[i][2] ;
  199.         lmat[7] = ldef_light[i][3] ;
  200.  
  201.         lmdef(DEFMATERIAL, NUM_MATERIALS+1, SIZE(lmat), lmat);
  202.         setmaterial(NUM_MATERIALS);
  203.         pushmatrix();
  204.         translate(ldef_light[i][9], ldef_light[i][10],
  205.             ldef_light[i][11]);
  206.         if (ldef_light[i][12] != 0.0)    /* Local Viewer? */
  207.         {
  208.             scale(0.02, 0.02, 0.02);
  209.             draw_icosa();
  210.             numdrawn += 20;
  211.         }
  212.         popmatrix();
  213.     }
  214.     return numdrawn;
  215. }
  216. /*
  217.  * Code produced by tm2code
  218.  *  Run on file icosa.TM
  219.  */
  220. /* VERTEX DATA */
  221. static float vdata[] = {
  222. 0.607062,0,-0.794654,
  223. -0.303531,0.525731,-0.794655,
  224. -0.303531,-0.525731,-0.794655,
  225. 0.491123,0.850651,-0.187592,
  226. -0.982247,0,-0.187592,
  227. 0.491123,-0.850651,-0.187592,
  228. -0.491123,0.850651,0.187592,
  229. 0.982247,0,0.187592,
  230. -0.491123,-0.850651,0.187592,
  231. 0.303531,0.525731,0.794655,
  232. -0.607062,0,0.794655,
  233. 0.303531,-0.525731,0.794655,
  234. };
  235.  
  236. void
  237. draw_icosa(void)
  238. {
  239.     bgntmesh();
  240.     n3f(vdata+15);
  241.     v3f(vdata+15);
  242.     n3f(vdata+33);
  243.     v3f(vdata+33);
  244.     n3f(vdata+21);
  245.     v3f(vdata+21);
  246.     n3f(vdata+27);
  247.     v3f(vdata+27);
  248.     swaptmesh();
  249.     n3f(vdata+9);
  250.     v3f(vdata+9);
  251.     swaptmesh();
  252.     n3f(vdata+0);
  253.     v3f(vdata+0);
  254.     n3f(vdata+15);
  255.     v3f(vdata+15);
  256.     n3f(vdata+6);
  257.     v3f(vdata+6);
  258.     swaptmesh();
  259.     n3f(vdata+24);
  260.     v3f(vdata+24);
  261.     n3f(vdata+33);
  262.     v3f(vdata+33);
  263.     n3f(vdata+30);
  264.     v3f(vdata+30);
  265.     n3f(vdata+27);
  266.     v3f(vdata+27);
  267.     n3f(vdata+18);
  268.     v3f(vdata+18);
  269.     n3f(vdata+9);
  270.     v3f(vdata+9);
  271.     n3f(vdata+3);
  272.     v3f(vdata+3);
  273.     n3f(vdata+0);
  274.     v3f(vdata+0);
  275.     swaptmesh();
  276.     n3f(vdata+6);
  277.     v3f(vdata+6);
  278.     swaptmesh();
  279.     n3f(vdata+12);
  280.     v3f(vdata+12);
  281.     n3f(vdata+18);
  282.     v3f(vdata+18);
  283.     swaptmesh();
  284.     n3f(vdata+30);
  285.     v3f(vdata+30);
  286.     swaptmesh();
  287.     n3f(vdata+24);
  288.     v3f(vdata+24);
  289.     n3f(vdata+6);
  290.     v3f(vdata+6);
  291.     endtmesh();
  292. }
  293.  
  294. /*
  295.  *    Static definitions for lighting.
  296.  */
  297.  
  298. char *matnames[NUM_MATERIALS] =
  299. {
  300.     "Brass",
  301.     "Shiny Brass",
  302.     "Pewter",
  303.     "Silver",
  304.     "Gold",
  305.     "Shiny Gold",
  306.     "Plaster",
  307.     "Red Plastic", 
  308.     "Green Plastic",
  309.     "Blue Plastic", 
  310. };
  311.  
  312. float ldef_material[][15] =
  313. {
  314.     {    /* BRASS */
  315.         AMBIENT, .35, .25,  .1,
  316.         DIFFUSE, .65, .5, .35,
  317.         SPECULAR, .8, .6, 0.,
  318.         SHININESS, 5.,
  319.         LMNULL
  320.     }, 
  321.     {    /* SHINY BRASS */
  322.         AMBIENT, .25, .15, 0.,
  323.         DIFFUSE, .65, .5, .35,
  324.         SPECULAR, .9, .6, 0.,
  325.         SHININESS, 10.,
  326.         LMNULL
  327.     }, 
  328.     {    /* PEWTER */
  329.         AMBIENT, .1, .1,  .1,
  330.         DIFFUSE, .6, .55 , .65,
  331.         SPECULAR, .9, .9, .95,
  332.         SHININESS, 10.,
  333.         LMNULL
  334.     }, 
  335.     {    /* SILVER */
  336.         AMBIENT, .4, .4,  .4,
  337.         DIFFUSE, .3, .3, .3,
  338.         SPECULAR, .9, .9, .95,
  339.         SHININESS, 30.,
  340.         LMNULL
  341.     }, 
  342.     {    /* GOLD */
  343.         AMBIENT, .4, .2, 0.,
  344.         DIFFUSE, .9, .5, 0.,
  345.         SPECULAR, .7, .7, 0.,
  346.         SHININESS, 10.,
  347.         LMNULL
  348.     }, 
  349.     {    /* SHINY GOLD */
  350.         AMBIENT, .4, .2, 0.,
  351.         DIFFUSE, .9, .5, 0.,
  352.         SPECULAR, .9, .9, 0.,
  353.         SHININESS, 2.,
  354.         LMNULL
  355.     }, 
  356.     {    /* PLASTER */
  357.         AMBIENT, .2, .2,  .2,
  358.         DIFFUSE, .95, .95, .95,
  359.         SPECULAR, 0., 0., 0.,
  360.         SHININESS, 1.,
  361.         LMNULL
  362.     }, 
  363.     {    /* RED PLASTIC */
  364.         AMBIENT, .3, .1, .1,
  365.         DIFFUSE, .5, .1, .1,
  366.         SPECULAR, .45, .45, .45,
  367.         SHININESS, 30.,
  368.         LMNULL
  369.     }, 
  370.     {    /* GREEN PLASTIC */
  371.         AMBIENT, .1, .3, .1,
  372.         DIFFUSE, .1, .5, .1,
  373.         SPECULAR, .45, .45, .45,
  374.         SHININESS, 30.,
  375.         LMNULL
  376.     },
  377.     {    /* BLUE PLASTIC */
  378.         AMBIENT, .1, .1, .3,
  379.         DIFFUSE, .1, .1, .5,
  380.         SPECULAR, .45, .45, .45,
  381.         SHININESS, 30.,
  382.         LMNULL
  383.     }
  384. } ;
  385.  
  386. char *lightnames[NUM_LIGHTS] =
  387. {
  388.     "White Infinite",
  389.     "Red Local",
  390.     "Blue Infinite",
  391.     "Green Local",
  392.     "Yellow Local",
  393.     "Magenta Infinite",
  394.     "White Local",
  395.     "Pink Infinite"
  396. } ;
  397.  
  398. float ldef_light[][14] =
  399. {
  400.     {    /* WHITE INFINITE */
  401.         LCOLOR, .8, .8, .8,
  402.         AMBIENT, 0., 0., 0.,
  403.         POSITION, -0.2, 0.2, 0.2, 0., 
  404.         LMNULL
  405.     },
  406.     {    /* RED LOCAL */
  407.         LCOLOR, .9, 0., 0.,
  408.         AMBIENT, .1, 0., 0.,
  409.         POSITION, 0.2, 0.2, 0.2, 1., 
  410.         LMNULL
  411.     }, 
  412.     {    /* BLUE INFINITE */
  413.         LCOLOR, .1, .1, .9,
  414.         AMBIENT, 0., 0., .05,
  415.         POSITION, 0.2, -0.2, 0.2, 0., 
  416.         LMNULL
  417.     }, 
  418.     {    /* GREEN LOCAL */
  419.         LCOLOR, .04, .9, .04,
  420.         AMBIENT, .0, 0., 0.,
  421.         POSITION, -0.2, -0.2, 0.2, 1., 
  422.         LMNULL
  423.     }, 
  424.     {    /* YELLOW LOCAL */
  425.         LCOLOR, .8, .8, .3,
  426.         AMBIENT, .05, .05, 0.,
  427.         POSITION, -0.2, 0.2, -0.2, 1., 
  428.         LMNULL
  429.     }, 
  430.     {    /* MAGENTA INFINITE */
  431.         LCOLOR,    .8, 0., .7,
  432.         AMBIENT, .0, .0, .0,
  433.         POSITION, 0.2, 0.2, -0.2, 0., 
  434.         LMNULL
  435.     }, 
  436.     {    /* WHITE LOCAL */
  437.         LCOLOR, 1.0, 1.0, 1.0,
  438.         AMBIENT, 0., 0., 0.,
  439.         POSITION, 0.2, -0.2, -0.2, 1., 
  440.         LMNULL
  441.     }, 
  442.     {    /* PINK INFINITE */
  443.         LCOLOR, .9, .5, .65,
  444.         AMBIENT, 0., 0., 0., 
  445.         POSITION, -0.2, -0.2, -0.2, 0., 
  446.         LMNULL
  447.     }, 
  448. };
  449.  
  450. char *lmodelnames[NUM_LMODELS] =
  451. {
  452.     "Infinite Viewer",
  453.     "Local Viewer", 
  454. };
  455.  
  456. float ldef_lmodel[][10] =
  457. {
  458.     {    /* Infinite viewer */
  459.         LOCALVIEWER, 0., 
  460.         AMBIENT, .3,  .3, .3, 
  461.         ATTENUATION, 1., 0., 
  462.         LMNULL
  463.     }, 
  464.     {    /* Local viewer */
  465.         LOCALVIEWER, 1.0, 
  466.         AMBIENT, .3,  .3,  .3, 
  467.         ATTENUATION, 1.0, 0.02, 
  468.         LMNULL
  469.     }, 
  470. };
  471.